/**
  * @file       list.h
  * @author     const_zpc (any question please send mail to const_zpc@163.com)
  * @brief      
  * @version    0.1
  * @date       2023-04-01
  * 
  * 
  * @par 使用方式: 
  * @code
  * 
  * @endcode
  * 
  * ********************************************************************************************************************
  */

/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/

#ifndef _COT_CONTAINER_LIST_H_
#define _COT_CONTAINER_LIST_H_

/* Includes ----------------------------------------------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

#ifdef __cplusplus
 extern "C" {
#endif 

typedef struct stcotListItem
{
    struct stcotListItem *pPrev;
    struct stcotListItem *pNext; 
    void *pData;
    uint32_t length;
} cotListItem_t;

typedef struct
{
    cotListItem_t node; 
    size_t count;
} cotList_t;


// 迭代器使用(自动指向下一个)
#define for_list_each(item, list) for (cotListItem_t *item = cotList_Begin(&list); item != cotList_End(&list); item = cotList_Next(item))

// 反向迭代器使用(自动指向下一个)
#define for_list_each_r(item, list) for (cotListItem_t *item = cotList_rBegin(&list); item != cotList_rEnd(&list); item = cotList_rNext(item))

// 迭代器使用(需要在循环内调用 item = cotList_Next(item) 指向下一个)
#define for_list(item, list) for (cotListItem_t *item = cotList_Begin(&list); item != cotList_End(&list);)

// 反向迭代器使用(需要在循环内调用 item = cotList_rNext(item) 指向下一个)
#define for_list_r(item, list) for (cotListItem_t *item = cotList_rBegin(&list); item != cotList_rEnd(&list);)


extern void cotList_Init(cotList_t *pList);

/** 迭代器 */

extern cotListItem_t *cotList_Begin(cotList_t *pList);
extern cotListItem_t *cotList_End(cotList_t *pList);
extern cotListItem_t *cotList_Next(cotListItem_t *pListItem);
extern cotListItem_t *cotList_rBegin(cotList_t *pList);
extern cotListItem_t *cotList_rEnd(cotList_t *pList);
extern cotListItem_t *cotList_rNext(cotListItem_t *pListItem);

/** 元素访问 */

extern cotListItem_t *cotList_Front(cotList_t *pList);
extern cotListItem_t *cotList_Back(cotList_t *pList);

/** 容量 */

extern bool cotList_Empty(cotList_t *pList);
extern size_t cotList_Size(cotList_t *pList);

/** 修改 */

extern void cotList_Clear(cotList_t *pList);
extern void cotList_Insert(cotList_t *pList, cotListItem_t *pListItem, const void *pdata, uint32_t length);
extern void cotList_InsertItem(cotList_t *pList, cotListItem_t *pListItem, cotListItem_t *pNewItem);
extern cotListItem_t * cotList_Erase(cotList_t *pList, cotListItem_t *pListItem);
extern void cotList_PushFront(cotList_t *pList, const void *pdata, uint32_t length);
extern void cotList_PopFront(cotList_t *pList);
extern void cotList_PushBack(cotList_t *pList, const void *pdata, uint32_t length);
extern void cotList_PopBack(cotList_t *pList);
extern void cotList_Swap(cotList_t *pList, cotList_t *pNewList);


#ifdef __cplusplus
 }
#endif

#endif // !_COT_CONTAINER_LIST_H_
